

use oss_rust_sdk::async_object::AsyncObjectAPI;
use oss_rust_sdk::prelude::OSS;
use std::collections::HashMap;
use std::fs::{File};
use std::io::{Read, Write};
use std::path::Path;
use std::{fs, str};

///oss操作时的相关配置
pub struct OssConfig {
    access_key: String,
    access_sec: String,
    pub end_point: String,
    pub bucket: String,
    pub path: Option<String>,
    pub dw_uri: Option<String>,
}

impl OssConfig {
    pub fn new(access_key: String, access_sec: String, end_point: String, bucket: String) -> Self {
        Self {
            access_key,
            access_sec,
            end_point,
            bucket,
            path: None,
            dw_uri: None,
        }
    }

    pub fn set_path(&mut self, path: Option<String>) {
        self.path = path;
    }
}

// todo
// oss以及对应相关操作远端的库可以单独抽成一个模块

// const ACCESS_KEY: &str = "I3qKdJMQC8TiuTCy";
// const ACCESS_SEC: &str = "MX0mTN960SezGAroN4Ldh1VgxSbf9g";
//
// const END_POINT: &str = "oss-cn-beijing.aliyuncs.com";
// const BUCKET: &str = "ccpm-plugins";

///下载文件
pub async fn download<'a>(oss_config: &OssConfig, remote: &'a str, local: &'a str) -> Option<File> {
    let oss_instance = OSS::new(
        &oss_config.access_key,
        &oss_config.access_sec,
        &oss_config.end_point,
        &oss_config.bucket,
    );
    let path_to_write = Path::new(local);

    let f = oss_instance.get_object(remote, None::<HashMap<&str, &str>>, None).await;
    if f.is_ok() {
        let mut file = File::create(path_to_write).unwrap();
        let _ = file.write_all(&f.unwrap());
        return Some(file);
    }
    return None;
}

pub async fn upload(oss_config: &OssConfig, local: &str, remote: &str) -> Option<bool> {
    let oss_instance = OSS::new(
        &oss_config.access_key,
        &oss_config.access_sec,
        &oss_config.end_point,
        &oss_config.bucket,
    );

    let mut f = File::open(local).expect("no file found");
    let mt = fs::metadata(local).expect("unable to read metadata");
    let mut buffer = vec![0; mt.len() as usize];
    f.read(&mut buffer).expect("read file raise error");
    let _ = oss_instance
        .put_object(&buffer, remote, None::<HashMap<&str, &str>>, None)
        .await;
    return Some(true);
}

#[test]
pub fn test() {
    println!("test in oss");
    // use std::time::SystemTime;
    // let mut rt = Runtime::new().unwrap();
    // rt.block_on(async move {
    //     download("plugins/goremote@v0.0.1.zip", "./aa.zip").await;
    //     upload("./aa.zip", "plugins/goremote@v0.0.2.zip").await;
    // });
    // rt.shutdown_background();
}
